﻿using MiniFox.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace MiniFox.Data.NativeClient
{
    /// <summary>
    /// 
    /// </summary>
    public class DataProvider : DataProviderBase
    {
        private Database _db;
        private string _connectionName;
        private int _commandTimeOut;

        #region constructor

        /// <summary>
        /// 使用指定连接名称构建数据提供者
        /// </summary>
        /// <param name="connectionName"></param>
        public DataProvider(string connectionName) : this(connectionName, 30)
        {
        }
        
        /// <summary>
        /// 使用指定连接名称构建数据提供者，并设置命令执行超时时间
        /// </summary>
        /// <param name="connectionName"></param>
        /// <param name="commandTimeOut"></param>
        public DataProvider(string connectionName, int commandTimeOut)
        {
            this._connectionName = connectionName;
            this._commandTimeOut = commandTimeOut;
            this._db = Database.CreateDatabase(_connectionName);
            this._db.ExecuteTimeout = commandTimeOut;
        }

        #endregion
        /// <summary>
        /// 
        /// </summary>
        public string ConnectionName
        {
            get
            {
                return _connectionName;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        protected int CommandTimeOut
        {
            get
            {
                return _commandTimeOut;
            }
        }
        /// <summary>
        /// 当前要访问的数据库对象
        /// </summary>
        public Database DataBase
        {
            get { return _db; }
        }

        #region Insert、Update、Delete
        /// <summary>
        /// 将实体插入到数据库中对应的表中
        /// </summary>
        /// <param name="entities">包含数据的实体</param>
        /// <returns>操作是否成功</returns>
        public override int Insert<TEntity>(params TEntity[] entities)
        {
            int rowcount = 0;
            //
            if (entities == null || entities.Length <= 0)
                return rowcount;
            IDataOperation<TEntity> dataoper = this.DataBase.CreateDataOperation<TEntity>();
            //
            this.OnDataInserting(entities);
            foreach (var entity in entities)
                rowcount += dataoper.ExecuteInsert(entity);
            this.OnDataInserted((rowcount > 0), entities);
            return rowcount;
        }
        /// <summary>
        /// 修改数据库中对应表的数据
        /// </summary>
        /// <param name="entities">包含数据的实体</param>
        /// <returns>操作是否成功</returns>
        public override int Update<TEntity>(params TEntity[] entities)
        {
            int rowcount = 0;
            //
            if (entities == null || entities.Length <= 0)
                return rowcount;
            IDataOperation<TEntity> dataoper = this.DataBase.CreateDataOperation<TEntity>();
            //
            this.OnDataUpdating(entities);
            foreach (var entity in entities)
                rowcount += dataoper.ExecuteUpdate(entity);
            this.OnDataUpdated((rowcount > 0), entities);
            return rowcount;
        }
        /// <summary>
        /// 删除数据库中对应表的数据
        /// </summary>
        /// <param name="entities">包含数据的相关实体</param>
        /// <returns>操作是否成功</returns>
        public override int Delete<TEntity>(params TEntity[] entities)
        {
            int rowcount = 0;
            //
            if (entities == null || entities.Length <= 0)
                return rowcount;
            IDataOperation<TEntity> dataoper = this.DataBase.CreateDataOperation<TEntity>();
            //
            this.OnDataDeleting(entities);
            foreach (var entity in entities)
                rowcount += dataoper.ExecuteDelete(entity);
            
            this.OnDataDeleted((rowcount > 0), entities);
            return rowcount;
        }

        #endregion

        #region 获取查询命令对象
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <returns></returns>
        public override IDataQuery<TEntity> GetDataQuery<TEntity>()
        {
            IDataQuery<TEntity> query = this.DataBase.CreateDataQuery<TEntity>();
            return query;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <returns></returns>
        public override IObjectQuery<TEntity> GetObjectQuery<TEntity>()
        {
            IObjectQuery<TEntity> query = this.DataBase.CreateObjectQuery<TEntity>();

            return query;
        }
        #endregion

    }

}
